﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;

namespace HydrographicSurvey.HYTCPServer {
    public class ClientAsync {
        private readonly IClientService _clientService;
        public ClientAsync(IClientService clientService) {
            _clientService = clientService ?? new HttpClientService();
        }

#if DEBUG
        private const string URI = "http://localhost/test/AddLog";
#else
        //private const string URI = "http://58.216.149.54:82/test/AddLog";
        private const string URI = "http://localhost/test/AddLog";
#endif
        public ManualResetEvent tcpClientConnected = new ManualResetEvent(false);

        // Accept one client connection asynchronously.
        public void DoBeginAcceptTcpClient(TcpListener listener) {
            // Set the event to nonsignaled state.
            tcpClientConnected.Reset();

            // Start to listen for connections from a client.
            Console.WriteLine("Waiting for a connection...");

            // Accept the connection. 
            // BeginAcceptSocket() creates the accepted socket.
            listener.BeginAcceptTcpClient(
                new AsyncCallback(DoAcceptTcpClientCallback),
                listener);

            // Wait until a connection is made and processed before 
            // continuing.
            tcpClientConnected.WaitOne();
        }

        // Process the client connection.
        public void DoAcceptTcpClientCallback(IAsyncResult ar) {
            // Get the listener that handles the client request.
            TcpListener listener = (TcpListener)ar.AsyncState;

            // End the operation and display the received data on 
            // the console.
            TcpClient client = listener.EndAcceptTcpClient(ar);

            DoTcpClient(client);

            // Signal the calling thread to continue.
            tcpClientConnected.Set();
        }
        private void DoTcpClient(TcpClient client) {
            NetworkStream netStream = null;
            try {
                // Uses the GetStream public method to return the NetworkStream.
                netStream = client.GetStream();

                if (netStream.CanRead) {
                    int size = 44;
                    // Reads NetworkStream into a byte buffer.
                    byte[] bytes = new byte[size];

                    // Read can return anything from 0 to numBytesToRead. 
                    // This method blocks until at least one byte is read.
                    netStream.Read(bytes, 0, size);

                    // Returns the data received from the host to the console.
                    LogDTO logDto = _clientService.CoventToLog(bytes);
                    _clientService.LogAddService(URI, logDto);

                    Console.Write("BaseData:");
                    foreach (byte b in bytes) {
                        Console.Write("{0:X2} ", b);
                    }
                    Console.Write("\n");

                    //Console.WriteLine("This is what the host returned to you: " + returndata);

                } else {
                    Console.WriteLine("You cannot read data from this stream.");
                }
            } catch (Exception e) {
                Console.WriteLine(e.Message);
            } finally {
                netStream.Close();
                client.Close();
                // Process the connection here. (Add the client to a
                // server table, read data, etc.)
                Console.WriteLine("Client connected completed");
            }
        }
    }
}
